import { ITypeEntity, ITypeEntityField } from '@/types/modules/superType/types';
import { getPureValue, getStateDefaultValue } from '@/types/modules/superType/utils/transformValue';
import { getTypeById, getTypeByParams } from '@/utils/editor-adapter/editorResource';
import {
  InterpretDataSourceConfig,
  IPublicTypeProjectSchema,
  IPublicTypeRootSchema,
} from '@alilc/lowcode-types';

/**
 * 根据DataType生成
 */
export const dataTypeToSchema = async (
  projectSchema: IPublicTypeProjectSchema | null,
  schema: IPublicTypeRootSchema,
  dataType: ITypeEntity,
  isGlobal?: boolean,
): Promise<IPublicTypeRootSchema | IPublicTypeProjectSchema> => {
  let dataTypes = [dataType];
  let fields = dataType.fields?.slice() || [];
  const isUpdateGlobalData = dataType.type === 'data' && !dataType.fileName;
  if (isUpdateGlobalData) {
    dataTypes = await getTypeByParams({ type: 'data', fileName: undefined });
    fields = dataTypes.reduce((pre, cur) => pre.concat(cur.fields || []), []);
  }
  let state: IPublicTypeRootSchema['state'] = getStateDefaultValue(fields);
  const dataSourceList: InterpretDataSourceConfig[] = [];
  for (const field of fields) {
    const { apiOptions, apiImport } = field;
    if (!field.apiImportEntity) {
      field.apiImportEntity = await getTypeById(apiImport);
    }
    if (field.isApi && apiOptions) {
      const { willFetch, dataHandler, errorHandler } = apiOptions;
      const dataSourceItem: InterpretDataSourceConfig = {
        id: field.name,
        isInit:
          schema?.componentName === 'Component'
            ? false
            : typeof field.isInit === 'boolean'
            ? field.isInit
            : false,
        isSync: typeof field.isSync === 'boolean' ? field.isSync : false,
        type: 'fetch',
        options: await createApiOptions(field.apiImportEntity, apiOptions),
        willFetch,
        dataHandler,
        errorHandler,
      };
      dataSourceList.push(dataSourceItem);
    }
  }
  const _schema = isGlobal ? projectSchema : schema;
  return {
    ..._schema,
    [isGlobal ? 'constants' : 'state']: state,
    dataSource: {
      ..._schema.dataSource,
      list: dataSourceList,
    },
  } as IPublicTypeRootSchema | IPublicTypeProjectSchema;
};

export const createApiOptions = async (
  apiType?: ITypeEntity,
  apiOptions?: ITypeEntityField['apiOptions'],
) => {
  const { uri, contentType, method, isCors, fkId } = apiType || {};
  let _uri = apiOptions.uri;
  if (!_uri) {
    _uri = await getRealUri(apiType)
  }
  try {
    const options: InterpretDataSourceConfig['options'] = {
      uri: _uri,
      contentType: apiOptions.contentType || contentType,
      method: apiOptions.method || method,
      isCors: typeof apiOptions.isCors === 'boolean' ? apiOptions.isCors : isCors,
      params: getPureValue(apiOptions.params || {}),
      pathParams: getPureValue(apiOptions.pathParams || {}),
      headers: getPureValue(apiOptions.headers || {}),
      timeout: apiOptions.timeout || apiType?.timeout,
    };
    return options as any;
  } catch (e) {
    console.log('[err] ', e);
  }
  return undefined;
};

export const getRealUri = async (apiType: ITypeEntity) => {
  if (!apiType) return null;
  const { fkId, uri } = apiType;
  const docType = await getTypeById(fkId);
  let _uri = uri;
  if (docType && docType.type === 'api-import') {
    if (!(uri && uri.slice(0, 4) === 'http')) {
      _uri = (docType.host || '') + (docType.basePath || '') + _uri;
    }
  }
  return _uri;
};
